#include "stands.h"

GLuint Person::index = -100;
int Person::totalJumpTime = 1;
int Person::jumpHeight = 1;

Person::Person(){
	this->position = Vector3();
	for(int i = 0; i < 5; i++){
		for(int j = 0; j < 4; j++){
			personColors[i][j] = RangeRand(0, 1);
		}
	}
	this->currJumpTime = 0;
	this->goingUp = true;

}

Person::Person(Vector3 position, Vector3 velocity, Vector3 goToPos){
	this->position = position;
	this->goToPos = goToPos;
	this->walkingVelocity = velocity;
	this->walkingState = 0;
	for(int i = 0; i < 5; i++){
		for(int j = 0; j < 4; j++){
			personColors[i][j] = RangeRand(0, 1);
		}
	}
	this->currJumpTime = 0;
	this->goingUp = true;
}

void Person::setupDisplayList(){
	index = glGenLists(5);
	

	glNewList(index, GL_COMPILE);
		GLUquadricObj* body = gluNewQuadric();
		glPushMatrix();
			glTranslatef(-.125f, .05f, 0);
			gluSphere(body, .05, 20, 20);
			glTranslatef(.25f, 0, 0);
			gluSphere(body, .05, 20, 20);
		glPopMatrix();
		gluDeleteQuadric(body);
	glEndList();

	glNewList(index + 1, GL_COMPILE);
		glPushMatrix();
			glTranslated(0, .09, 0);
			glRotated(-90.0, 1, 0, 0);
			glutSolidCone(.175, .8, 20, 20);
		glPopMatrix();
	glEndList();

	glNewList(index + 2, GL_COMPILE);
		glPushMatrix();
			glPushMatrix();			
				glTranslated(.2, .5, 0);
				glScaled(.4, .04, .04);
				/*glBegin(GL_LINES);
					glVertex3f(0, 0, 0);
					glVertex3f(-.5f, 0, 0);
					glVertex3f(0, 0, 0);
					glVertex3f(.5f, 0, 0);
				glEnd();*/
				glutSolidCube(1);
			glPopMatrix();

			glPushMatrix();
				glTranslated(-.2, .5, 0);
				glScaled(.4, .04, .04);
				glutSolidCube(1);
			glPopMatrix();
		glPopMatrix();
	glEndList();

	glNewList(index + 3, GL_COMPILE);
		GLUquadricObj* body1 = gluNewQuadric();
		glPushMatrix();
			glTranslated(0, .825, 0);
			gluSphere(body, .175, 20, 20);

		glPopMatrix();
		gluDeleteQuadric(body1);
	glEndList();

	glNewList(index + 4, GL_COMPILE);
		GLUquadricObj* body2 = gluNewQuadric();
		glPushMatrix();
			glTranslated(0, .825, 0);
			glTranslated(-.05, .05, .175);
			gluSphere(body, .05, 20, 20);
			glTranslated(.1, 0, 0);
			gluSphere(body, .05, 20, 20);
		glPopMatrix();
		gluDeleteQuadric(body2);

	glEndList();
	

}

void Person::Draw(){
	float specReflection[] = { 0.3f, 0.3f, 0.3f, 1.0f };
	
	glPushMatrix();
		//glLoadIdentity();
		//glTranslateVector(this->position);
		glScalef(50.0f, 50.0f, 50.0f);

		glMateriali(GL_FRONT, GL_SHININESS, 100);
		glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);

		glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, personColors[0]);	
		glCallList(index);

		glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, personColors[1]);	
		glCallList(index + 1);

		glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, personColors[2]);	
		glCallList(index + 2);

		glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, personColors[3]);	
		glCallList(index + 3);

		glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, personColors[4]);	
		glCallList(index + 4);
	
	glPopMatrix();

}





Stands::Stands(){
	this->levels = 10;
	this->width = 100;
	this->position = Vector3();
	this->seatHeight = 10;
	index = glGenLists(1);
	glNewList(index, GL_COMPILE);
	glPushMatrix();
		for(int i = 0; i < levels; i++){
			glPushMatrix();
				glTranslatef(0, seatHeight, -(seatHeight/2.0f));
				glScalef(width, seatHeight, seatHeight * (levels - i));
				glutSolidCube(1);
			glPopMatrix();
		}
		glPushMatrix();
			glTranslatef(width/2 + 30, (seatHeight * levels)/2 - seatHeight/2, 0);
			glRotatef(45, 1, 0, 0);
			glScalef(60, 5, seatHeight * levels + 400);
			glutSolidCube(1);
		glPopMatrix();
	glPopMatrix();
	glEndList();
	numPeoplePerLevel = (int) width/60.0f - 1;
	for(int i = 0; i < levels; i++){
		for(int j = 0; j < numPeoplePerLevel; j++){
			goToPositions.push_back(Vector3((-width / 2) + 60 + 60.0f * j, (seatHeight/2.0f) + seatHeight * i, seatHeight * (levels - i)));
		}
	}
	
}

Stands::Stands(int levels, Vector3 position, float width, float seatHeight){
	this->levels = levels;
	this->position = position;
	this->width = width;
	this->seatHeight = seatHeight;
	index = glGenLists(1);
	glNewList(index, GL_COMPILE);
	glPushMatrix();
		for(int i = 0; i < levels; i++){
			glPushMatrix();
				glTranslatef(0, seatHeight * i, -(seatHeight/2.0f) * i);
				glScalef(width, seatHeight, seatHeight * (levels - i));
				glutSolidCube(1);
			glPopMatrix();
		}
		glPushMatrix();
			glTranslatef(width/2 + 30, (seatHeight * levels)/2 , 0);
			glRotatef(45, 1, 0, 0);
			glScalef(60, 5, seatHeight * levels + 400);
			glutSolidCube(1);
		glPopMatrix();

		glPushMatrix();
			glTranslatef(width/2 + 330, 300, -400);
			glRotatef(30, 1, 0, 0);
			glScalef(60, 5, 1600);
			glutSolidCube(1);
		glPopMatrix();

	glPopMatrix();
	glEndList();
	numPeoplePerLevel = (int) width/60.0f - 1;
	for(int i = 0; i < levels; i++){
		for(int j = 0; j < numPeoplePerLevel; j++){
			goToPositions.push_back(Vector3((-width / 2) + 60 + 60.0f * j, (seatHeight/2.0f) + seatHeight * i, seatHeight * (levels - i) - seatHeight/6 - seatHeight * (levels/2)));
		}
	}

	portalPosition = Vector3(width/2 + 330, 730, -1543 + seatHeight * 4);
}



void Stands::Draw(){

	float specReflection[] = { 0.3f, 0.3f, 0.3f, 1.0f };
	float black[] = { 0, 0, 0, 1.0f };
	float standsColor[] = {.8f, .5f, .3f };

	glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, standsColor);	
	glMateriali(GL_FRONT, GL_SHININESS, 100);
	glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);
	glCallList(index);
	glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, black);	
	glPushMatrix();
		glTranslatef(width/2 + 330, 750, - 1543 + seatHeight * 4);
		glScalef(2, 5, .1);
		glutSolidSphere(20, 20, 20);
	glPopMatrix();
	for(int i = 0; i < peopleInStands.size(); i++){
		glPushMatrix();
			glTranslateVector(peopleInStands[i].position);
			peopleInStands[i].Draw();

		glPopMatrix();
	}

}

Vector3 Stands::getPostition(){
	return position;
}

void Stands::updatePeople(double time){
	for(int i = 0; i < peopleInStands.size(); i++){
		peopleInStands[i].position = peopleInStands[i].position + (peopleInStands[i].walkingVelocity * time);
		switch(peopleInStands[i].walkingState){
			case 0:
				if(peopleInStands[i].position.y < seatHeight/2.0f){
					peopleInStands[i].position.y = seatHeight/2.0f;
					peopleInStands[i].walkingVelocity = Vector3(0, 0, PERSON_SPEED);
					peopleInStands[i].walkingState++;
				}
				break;
			case 1:
				if(peopleInStands[i].position.z > seatHeight * (levels / 2) - seatHeight/6){
					peopleInStands[i].position.z = seatHeight * (levels / 2) - seatHeight/6;
					peopleInStands[i].walkingVelocity = Vector3(-PERSON_SPEED, 0, 0);
					peopleInStands[i].walkingState++;
				}
				break;
			case 2:
				if(peopleInStands[i].position.x < width/2 + 30){
					peopleInStands[i].position.x = width/2 + 30;
					peopleInStands[i].walkingVelocity = Vector3(0, 1, -1).normalize() * PERSON_SPEED;
					peopleInStands[i].walkingState++;
				}
				break;
			case 3:
				if(peopleInStands[i].position.y > peopleInStands[i].goToPos.y){
					peopleInStands[i].position.y = peopleInStands[i].goToPos.y;
					peopleInStands[i].position.z = peopleInStands[i].goToPos.z;
					peopleInStands[i].walkingVelocity = Vector3(-PERSON_SPEED, 0, 0);
					peopleInStands[i].walkingState++;
				}
				break;
			case 4:
				if(peopleInStands[i].position.x < peopleInStands[i].goToPos.x){
					peopleInStands[i].position = peopleInStands[i].goToPos;
					peopleInStands[i].walkingState++;
					peopleInStands[i].walkingVelocity = Vector3();

				}
				break;
			case 5:
				peopleInStands[i].Jump(peopleInStands[i].currJumpTime, Person::totalJumpTime, Person::jumpHeight);
				break;


		}
		
	}

}

bool Stands::createPerson(){
	if(goToPositions.size() == 0)
		return false;
	peopleInStands.push_back(Person(portalPosition, Vector3(0, -1, sqrt(3.0)).normalize() * 150, goToPositions[0]));
	goToPositions.erase(goToPositions.begin());
	return true;
}

void Person::Jump(double &currJumpTime, double totalJumpTime, double jumpHeight)
{
	if (currJumpTime >= totalJumpTime)
	{
		currJumpTime = totalJumpTime;
		goingUp = false;
	}
	else if (currJumpTime <= 0)
	{
		currJumpTime = 0;
		goingUp = true;
		position.y = goToPos.y;
	}

	// Make person jump
	double newBodyPosition = sin(currJumpTime/totalJumpTime * PI/2) * jumpHeight;
	glPushMatrix();
		glTranslateVector(position);
		if (goingUp) 
			position.y += newBodyPosition;
		else 
			position.y -= newBodyPosition;
	glPopMatrix();

	if (goingUp) 
		currJumpTime += 0.05;
	else         
		currJumpTime -= 0.05;
}